﻿using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using TmU220PrintHelperV2d0.Service;
using TmU220PrintHelperV2d0.Singleton;
using ZhangLogSysV1d0;
/// <summary>
/// 打印任务
/// zhangfujian-2019-01
/// </summary>
namespace TmU220PrintHelperV2d0.Entity
{
    /// <summary>
    /// 打印任务,一个打印任务包含多个任务项
    /// </summary>
    [Serializable]
    public class PrintTaskV2d0
    {
        /// <summary>
        /// 打印任务的添加时间
        /// </summary>
        public DateTime AddTime { get; set; }
        /// <summary>
        /// 是否繁体
        /// </summary>
        public int IsTraditional;
        /// <summary>
        /// 打印任务发送给打印机（进行打印）的次数（只要打印任务发送给打印机，次数就加1，无论是否打印成功）
        /// </summary>
        public int CountOfSendingToPrinter { get; set; }
        /// <summary>
        /// 使用的模板名
        /// </summary>
        public string UsingPrintTempletName { get; set; }
        /// <summary>
        /// 打印任务的数据，来自远程数据表。包含主数据和明细数据
        /// </summary>
        public rms_order_print_main DataOfPrintTask { get; set; }
        /// <summary>
        /// 打印任务包含的打印任务项列表
        /// </summary>
        public List<PrintTaskItemV2d0> PrintTaskItemList { get; set; }
        /// <summary>
        /// 无参数构造函数
        /// </summary>
        public PrintTaskV2d0()
        {
            DataOfPrintTask = new rms_order_print_main();
            PrintTaskItemList = new List<PrintTaskItemV2d0>();
            UsingPrintTempletName = "TM-U220";
            CountOfSendingToPrinter = 0;
            IsTraditional = 0;

        }
        /// <summary>
        /// 根据打印任务数据和打印模板构造打印任务类
        /// </summary>
        /// <param name="sourcePrintData">源打印数据，包括主打印数据表记录和明细打印数据表记录</param>
        /// <param name="printTempletName">打印模板名称</param>
        public PrintTaskV2d0(rms_order_print_main sourcePrintData, string printTempletName)
        {
            try
            {
                //模板都是简体
                IsTraditional = 0;
                //将源打印数据赋值给打印任务对象的数据字段
                DataOfPrintTask = sourcePrintData;
                string targetPrinterName = sourcePrintData.printer;
                string deviceType = PrinterInfoSetSingletonV2d0.Instance.GetDeviceTypeByPrinterName(targetPrinterName);
                UsingPrintTempletName = printTempletName;
                PrintTaskItemList = new List<PrintTaskItemV2d0>();
                //用源打印数据更新打印模板中的可替换元素，得到最终打印模板对象
                PrintTempletV2d0 finalPrintTemplet = GetFinalTemplet(sourcePrintData, printTempletName);
                //将最终打印模板的行转换为打印任务项。一个打印任务项对应一个模板行（明细行展开）
                foreach(var templetRow in finalPrintTemplet.PrintTempletRowList)
                {
                    // 检查模板行的元素内容是否包含【NO.0】
                    var itemFinded = templetRow.TempletElementList.FirstOrDefault(x => x.ContentText == "NO.0");
                    //如果该模板行所有元素的内容均不包含【NO.0】，则该将该模板行转换为打印任务项
                    if (itemFinded==null)  PrintTaskItemList.Add(new PrintTaskItemV2d0(templetRow, deviceType));
                }
                CountOfSendingToPrinter = 0;
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
        }
    
        /// <summary>
        /// 计算字符串的点个数，一个汉字16+2个点宽（左右间距1个点宽，两个半点），一个asc字符9+3个点宽（左右间距1.5个点宽，三个半点），
        /// 一行总共400个点宽        
        /// </summary>
        /// <param name="targetString"></param>
        /// <param name="doubleWidth">是否倍宽</param>
        /// <returns>单位半点</returns>
        public static int GetStringDotCount(string targetString, bool isDoubleWidth = false)
        {
            int length = 0;
            for (int i = 0; i < targetString.Length; i++)
            {
                if ((int)targetString[i] > 128) length += 18;//汉字
                else length += 12;//asc字符
            }
            if (isDoubleWidth) length = length * 2;
            return length;
        }
        /// <summary>
        /// 在左对齐字符串和右对其字符串中间添加若干空格，组合很一个完整的打印行。使左对齐字符串靠左边打印，右对齐字符串靠右打印
        /// </summary>
        /// <param name="leftAlignString">左对齐字符串</param>
        /// <param name="rightAlignString">右对其字符串</param>
        /// <param name="isDoubleWidth">是否倍宽</param>
        /// <param name="validPrintAreaWidth">可打印区域的宽度，单位：点（打印机单位）</param>
        /// <returns>一个完整打印行的字符串</returns>
        public static string GetSingleLineStringLeftRight(string leftAlignString, string rightAlignString, bool isDoubleWidth,int validPrintAreaWidth=396)
        {
            string resultString = string.Empty;
            try
            {
                string spaceString = new string(' ',80);
                StringBuilder sBuilder = new StringBuilder(leftAlignString + rightAlignString);
                if (GetStringDotCount(sBuilder.ToString(), isDoubleWidth) <= validPrintAreaWidth)
                {
                    sBuilder = new StringBuilder(leftAlignString + spaceString + rightAlignString);
                    while (GetStringDotCount(sBuilder.ToString(), isDoubleWidth) > validPrintAreaWidth)
                    {
                        sBuilder.Replace(" ", "", leftAlignString.Length, 1);
                    }
                }
                else
                {
                    while (GetStringDotCount(sBuilder.ToString(), isDoubleWidth) > validPrintAreaWidth)
                    {
                        sBuilder = sBuilder.Remove(sBuilder.Length - 1, 1);
                    }
                }
                resultString = sBuilder.ToString();
            }
            catch(Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return resultString;
        }
        /// <summary>
        /// 生成一个完整的打印行字符串，其中包含左对齐字符串，居中对齐字符串，右对齐字符串，字符串之间填充若干空格
        /// </summary>
        /// <param name="leftAlignString"></param>
        /// <param name="centerAlignString"></param>
        /// <param name="rightAlignString"></param>
        /// <param name="isDoubleWidth"></param>
        /// <returns></returns>
        public static string GetSingleLineStringLeftCenterRight(string leftAlignString,string centerAlignString, string rightAlignString, bool isDoubleWidth, int validPrintAreaWidth = 394)
        {
            string resultString = string.Empty;
            try
            {
                string spaceString = new string(' ', 80);
                StringBuilder sBuilder = new StringBuilder(leftAlignString + centerAlignString + rightAlignString);
                if (GetStringDotCount(sBuilder.ToString(), isDoubleWidth) <= validPrintAreaWidth)
                {
                    //将centerAlignString均分成两部分
                    string leftPart = centerAlignString.Substring(0, centerAlignString.Length / 2);
                    string rightPart = centerAlignString.Substring(centerAlignString.Length / 2);
                    string resultLeft = GetSingleLineStringLeftRight(leftAlignString, leftPart, isDoubleWidth, validPrintAreaWidth/2);
                    string resultRight = GetSingleLineStringLeftRight(rightPart, rightAlignString, isDoubleWidth, validPrintAreaWidth/2);
                    resultString = resultLeft + resultRight;
                }
                else
                {
                    while (GetStringDotCount(sBuilder.ToString(), isDoubleWidth) > validPrintAreaWidth)
                    {
                        sBuilder = sBuilder.Remove(sBuilder.Length - 1, 1);
                    }
                    resultString = sBuilder.ToString();
                }
            }
            catch(Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return resultString;
        }
        /// <summary>
        /// 用源打印数据,填充将打印模板的可替换元素,得到最终打印模板
        /// </summary>
        /// <param name="mainTableRecord">源打印数,主数据和明细数据</param>
        /// <param name="templetName">模板名称</param>
        public static PrintTempletV2d0 GetFinalTemplet(rms_order_print_main mainTableData, string templetName)
        {
            PrintTempletV2d0 finalPrintTemplet = new PrintTempletV2d0();
            try
            {
                finalPrintTemplet.PrintTempletRowList.Clear();
                finalPrintTemplet.TempletName = "FinalPrint";
                //得到打印模板对象
                PrintTempletV2d0 printTemplet = PrintTempletSetSingletonV2d0.Instance.GetPrintTemplet(templetName);
                //遍历打印模板行列表
                foreach (var row in printTemplet.PrintTempletRowList)
                {
                    //得到模板行和源打印数据,生成该行对应的最终模板行列表
                    //模板头区,脚区的一个模板行对应一个最终模板打印行
                    //模板明细区，一个模板行对应多个最终模板打印行
                    List<PrintTempletRowV2d0> rowList = GetFinalRowList(mainTableData, row);
                    finalPrintTemplet.PrintTempletRowList.AddRange(rowList);
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return finalPrintTemplet;
        }
        /// <summary>
        /// 核心方法 
        /// 将打印模板行展开，包括明细（一条明细一个模板行）
        /// </summary>
        /// <param name="mainTableRecord"></param>
        /// <param name="printTempletRow"></param>
        /// <returns></returns>
        private static List<PrintTempletRowV2d0> GetFinalRowList(rms_order_print_main mainTableRecord, PrintTempletRowV2d0 printTempletRow)
        {
            List<PrintTempletRowV2d0> printTempletRowList = new List<PrintTempletRowV2d0>();
            try
            {
                //判断打印模板行所属的区域,明细区域和头脚区域处理方式不同
                if (printTempletRow.AreaType == AreaTypeV2d0.Detail)
                {
                    foreach (var detailRecord in mainTableRecord.detailList)
                    {
                        PrintTempletRowV2d0 finalRow = HotchPotchV2d0.Clone<PrintTempletRowV2d0>(printTempletRow);
                        finalRow.TempletElementList.Clear();
                        foreach (var element in printTempletRow.TempletElementList)
                        {
                            PrintTempletElementV2d0 finalElement = GetFinalDetailElement(detailRecord, element);
                            finalRow.TempletElementList.Add(finalElement);
                        }
                        printTempletRowList.Add(finalRow);
                    }
                }
                else
                {
                    PrintTempletRowV2d0 finalRow = HotchPotchV2d0.Clone<PrintTempletRowV2d0>(printTempletRow);
                    finalRow.TempletElementList.Clear();
                    foreach (var element in printTempletRow.TempletElementList)
                    {
                        PrintTempletElementV2d0 finalElement = GetFinalHeaderFooterElement(mainTableRecord, element);
                        finalRow.TempletElementList.Add(finalElement);
                    }
                    printTempletRowList.Add(finalRow);
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return printTempletRowList;
        }

        /// <summary>
        /// 根据源数据和模板元素，得到用于最终用于打印模板元素
        /// </summary>
        /// <param name="detailTableRecord"></param>
        /// <param name="printTempletElement"></param>
        /// <returns></returns>
        private static PrintTempletElementV2d0 GetFinalDetailElement(rms_order_print_detail detailTableRecord, PrintTempletElementV2d0 printTempletElement)
        {
            //深度复制
            PrintTempletElementV2d0 finalElement = HotchPotchV2d0.Clone<PrintTempletElementV2d0>(printTempletElement);
            try
            {
                string contentOfElement= finalElement.ContentText;
                string startString = "";
                string endString = "";

                string elementContentText = finalElement.ContentText;
                string firstPart = HotchPotchV2d0.GetSplitPartByIndex(elementContentText, 0);
                string secondPart = HotchPotchV2d0.GetSplitPartByIndex(elementContentText, 1);
                //如果元素内容为明细表字段，则根据属性得到最终打印内容字符串。
                //如果该元素内容不是明细表字段,则该内容就是最终打印字符串,无需处理
                if (firstPart == "Detail" && secondPart != null)
                {
                    //打印内容判断，数量做特别处理，如果是整数则不显示小数点
                    if (detailTableRecord.qty<0.9)
                    {
                        if (secondPart == "qty"|| detailTableRecord.is_modifier==true) finalElement.ContentText = "  ";
                        else finalElement.ContentText = HotchPotchV2d0.GetObjectPropertyStringValue(secondPart, detailTableRecord);
                    }
                    else
                    {
                        if (secondPart != null && secondPart == "qty"&& detailTableRecord.is_modifier == false)
                        {
                            decimal qtyValue = Convert.ToDecimal(HotchPotchV2d0.GetObjectProperty(secondPart, detailTableRecord));
                            finalElement.ContentText = startString + qtyValue.ToString("0.##") + endString;
                        }
                        else if (secondPart != null && (secondPart == "qty" ||secondPart=="spec")&& detailTableRecord.is_modifier == true)
                        {
                            finalElement.ContentText =" ";
                        }
                        else
                        {
                            //得到该属性名称对应明细表的属性值 明细表
                            finalElement.ContentText = startString + HotchPotchV2d0.GetObjectPropertyStringValue(secondPart, detailTableRecord) + endString;
                        }
                    }
                    // 数量大于1 ，用红色进行打印 这里进行
                    if(detailTableRecord.qty>1)
                    {
                        finalElement.FontColor = "Red";
                    }
                    // 特别处理，用红色进行打印
                    if(detailTableRecord.is_modifier.HasValue&&detailTableRecord.is_modifier.Value)
                    {
                        finalElement.FontColor = "Red";
                    }
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return finalElement;
        }

        private static PrintTempletElementV2d0 GetFinalHeaderFooterElement(rms_order_print_main mainTableRecord, PrintTempletElementV2d0 printTempletElement)
        {
            //深度复制
            PrintTempletElementV2d0 finalElement = HotchPotchV2d0.Clone<PrintTempletElementV2d0>(printTempletElement);
            try
            {
                string content= finalElement.ContentText;
                // 判断元素是否包含数据表字段
                string frontString = "";
                string middleString = "";
                string backString = "";
                HotchPotchV2d0.ParseBraceString(content, out frontString, out middleString, out backString);
                if (string.IsNullOrEmpty(middleString))
                {
                    // 如果字符串无大括号，则继续使用旧的处理方法
                    string elementContentText = finalElement.ContentText;
                    string firstPart = HotchPotchV2d0.GetSplitPartByIndex(elementContentText, 0);
                    string secondPart = HotchPotchV2d0.GetSplitPartByIndex(elementContentText, 1);
                    //如果元素内容为明细表字段，则根据属性得到最终打印内容字符串。
                    //如果该元素内容不是明细表字段,则该内容就是最终打印字符串,无需处理
                    if (firstPart == "Main" && !string.IsNullOrEmpty(secondPart))
                    {
                        //得到该属性名称对应明细表的属性值 明细表
                        //var propertyValue = mainTableRecord.GetPropertyValue(secondPart);
                        var propertyValue = HotchPotchV2d0.GetObjectPropertyStringValue(secondPart, mainTableRecord);
                        finalElement.ContentText = propertyValue != null ? propertyValue.ToString() : string.Empty;
                    }
                }
                else
                {
                    //如果字符串有大括号，则使用新的处理方法
                    // 如果字符串无大括号，则继续使用旧的处理方法
                    string elementContentText = middleString;
                    string firstPart = HotchPotchV2d0.GetSplitPartByIndex(elementContentText, 0);
                    string secondPart = HotchPotchV2d0.GetSplitPartByIndex(elementContentText, 1);
                    //如果元素内容为明细表字段，则根据属性得到最终打印内容字符串。
                    //如果该元素内容不是明细表字段,则该内容就是最终打印字符串,无需处理
                    if (firstPart == "Main" && !string.IsNullOrEmpty(secondPart))
                    {
                        //得到该属性名称对应明细表的属性值 明细表
                        //var propertyValue = mainTableRecord.GetPropertyValue(secondPart);
                        var propertyValue = HotchPotchV2d0.GetObjectPropertyStringValue(secondPart, mainTableRecord);
                        string value = propertyValue != null ? propertyValue.ToString() : string.Empty;
                        finalElement.ContentText = frontString+value+backString;
                    }

                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return finalElement;
        }
    }
}
